package com.healthtop.service.impl;

import com.google.common.collect.Maps;
import com.healthtop.common.HttpMessageResult;
import com.healthtop.common.ResponseStatus;
import com.healthtop.common.Specification;
import com.healthtop.dao.XsUserDao;
import com.healthtop.dto.LoginDto;
import com.healthtop.dto.RegisteredDto;
import com.healthtop.dto.SessionUserDto;
import com.healthtop.dto.XsUserDto;
import com.healthtop.model.XsRole;
import com.healthtop.model.XsUser;
import com.healthtop.model.XsUserRole;
import com.healthtop.service.DIYService;
import com.healthtop.service.XsRoleService;
import com.healthtop.service.XsUserRoleService;
import com.healthtop.service.XsUserService;
import com.healthtop.utils.*;

import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class XsUserServiceImpl implements XsUserService {

    @Autowired
    private DIYService diyService;

    @Autowired
    private XsUserDao xsUserDao;

    @Autowired
    private XsUserRoleService xsUserRoleService;

    @Override
    public XsUser login(LoginDto loginDto, HttpServletRequest request) {
        String verifyCode =request.getSession().getAttribute("verifyCode").toString().toLowerCase();
        XsUser user =new XsUser();
        if(verifyCode.equals(loginDto.getVerifyInput().toLowerCase())) {
            String userName =loginDto.getUserName();
            if(!ObjectUtils.isEmpty(userName)){
                userName=userName.trim();
            }
            user = CollectionUtils.getFirst(diyService.selectUser(userName));
            if (ObjectUtils.isEmpty(user)) {
                loginDto.failure(ResponseStatus.USER_NAME_NOT_EXISTS.status, ResponseStatus.USER_NAME_NOT_EXISTS.message);
            } else {
                String salt = user.getSalt();
                String encrypt = loginDto.getEncrypt();
                if (SecurityUtils.md5(encrypt, salt).equals(user.getPassWord())) {
                    SessionUserDto sessionUserDto = new SessionUserDto();
                    sessionUserDto.setUid(user.getUserId());
                    sessionUserDto.setUserName(user.getUserName());
                    List<XsRole> xsRoles = diyService.selectXsRoleByUid(user.getUserId());
                    sessionUserDto.setRoles(xsRoles);
                    UserUtils.setCurrentUser(sessionUserDto);
                } else {
                    loginDto.failure(ResponseStatus.LOGIN_ERROR_NOT_MATCH.status, ResponseStatus.LOGIN_ERROR_NOT_MATCH.message);
                }
            }
        }else{
            loginDto.failure(ResponseStatus.VERIFICATION_CODE_INPUT_ERROR.status, ResponseStatus.VERIFICATION_CODE_INPUT_ERROR.message);
        }
        return user;
    }

    @Override
    public XsUser registered(RegisteredDto registeredDto, HttpServletRequest request) {
        String verifyCode =request.getSession().getAttribute("verifyCode").toString().toLowerCase();
        XsUser user =new XsUser();
        if(verifyCode.equals(registeredDto.getVerifyInput().toLowerCase())) {
            Map map = Maps.newHashMap();
            String username =registeredDto.getUserName();
            String phoneNum =registeredDto.getPhoneNum();
            if(!ObjectUtils.isEmpty(phoneNum)){
                phoneNum = phoneNum.trim();
            }
            if(!ObjectUtils.isEmpty(username)){
                username = username.trim();
            }
            map.put("username",username);
            map.put("phoneNum",phoneNum);
            int count = diyService.selectXsUserCount(map);
            if(count>0){
                registeredDto.failure(ResponseStatus.IT_IS_ALREADY_REGISTERED.status,ResponseStatus.IT_IS_ALREADY_REGISTERED.message);
            }else{
                map.put("phoneNum","");
                count =diyService.selectXsUserCount(map);
                if(count>0){
                    registeredDto.failure(ResponseStatus.THE_USER_NAME_HAS_BEEN_USED.status,ResponseStatus.THE_USER_NAME_HAS_BEEN_USED.message);
                }else{
                    map.put("username","");
                    map.put("phoneNum",phoneNum);
                    count=diyService.selectXsUserCount(map);
                    if(count>0){
                        registeredDto.failure(ResponseStatus.THE_CELL_PHONE_NUMBER_HAS_BEEN_USED.status,ResponseStatus.THE_CELL_PHONE_NUMBER_HAS_BEEN_USED.message);
                    }else{
                        BeanUtils.copyProperties(registeredDto,user);
                        user.setCreateTime(new Date());
                        String salt = SecurityUtils.buildSalt(Specification.SaltLength.ENCRYPT_SALT_LENGTH.index);
                        user.setPassWord(SecurityUtils.md5(registeredDto.getEncrypt(), salt));
                        user.setSalt(salt);
                        user.setDelFalg("0");
                        xsUserDao.insert(user);
                        XsUserRole xsUserRole = new XsUserRole();
                        xsUserRole.setUserId(user.getUserId());
                        xsUserRole.setRoleId(1L);
                        xsUserRoleService.insert(xsUserRole);
                        SessionUserDto sessionUserDto = new SessionUserDto();
                        sessionUserDto.setUid(user.getUserId());
                        sessionUserDto.setUserName(user.getUserName());
                        List<XsRole> xsRoles = diyService.selectXsRoleByUid(user.getUserId());
                        sessionUserDto.setRoles(xsRoles);
                        UserUtils.setCurrentUser(sessionUserDto);
                    }
                }
            }
        }else{
            registeredDto.failure(ResponseStatus.VERIFICATION_CODE_INPUT_ERROR.status, ResponseStatus.VERIFICATION_CODE_INPUT_ERROR.message);
        }
      return user;
    }

    @Override
    public List<Map> selectUserByRoleId(long roleId) {
        List<XsUserRole> userRoles = xsUserRoleService.selectByRoleId(roleId);
        List<Long> urIds = new ArrayList<>();
        for(XsUserRole userRole: userRoles) {
            urIds.add(userRole.getUserId());
        }
        List<XsUser> users = xsUserDao.selectUserAll();
        List<Map> arrays = new ArrayList<>();
        for(XsUser user: users) {
            Map map = new HashMap();
            map.put("id", user.getUserId());
            map.put("name", user.getUserName());
            if(urIds.contains(user.getUserId())) {
                map.put("checked", true);
            }
            arrays.add(map);
        }
        return arrays;
    }

    @Override
    public boolean userNameIsNull(String userName,Long userId) {
        Map map = Maps.newHashMap();
        map.put("username",userName);
        map.put("userId",userId);
        int count = diyService.selectXsUserCount(map);
        if(count>0){
           return false;
        }else{
            return true;
        }
    }

    @Override
    public boolean phoneNumIsNull(String phoneNum,Long userId) {
        Map map = Maps.newHashMap();
        map.put("phoneNum",phoneNum);
        map.put("userId",userId);
        int count = diyService.selectXsUserCount(map);
        if(count>0){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public XsUserDto forward(XsUserDto xsUserDto) {
        if(Specification.OperateMode.UPDATE.index==xsUserDto.getMode()){
            XsUser xsUser = xsUserDao.selectUserByUserId(xsUserDto.getUserId());
            BeanUtils.copyProperties(xsUser,xsUserDto);
        }
        return xsUserDto;
    }

    @Override
    public void operate(XsUserDto xsUserDto) {
        XsUser xsUser = new XsUser();
        BeanUtils.copyProperties(xsUserDto,xsUser);
        if(Specification.OperateMode.CREATE.index==xsUserDto.getMode()){
            String salt = SecurityUtils.buildSalt(Specification.SaltLength.ENCRYPT_SALT_LENGTH.index);
            xsUser.setPassWord(SecurityUtils.md5(xsUserDto.getPassWord(), salt));
            xsUser.setSalt(salt);
            xsUser.setCreateTime(new Date());
            xsUser.setCreateUser(UserUtils.getCurrentUser().getUid());
            xsUser.setDelFalg("0");
            xsUserDao.insert(xsUser);
        }else if(Specification.OperateMode.UPDATE.index==xsUserDto.getMode()){
            xsUser.setUpdateTime(new Date());
            xsUser.setUpdateUser(UserUtils.getCurrentUser().getUid());
            xsUserDao.update(xsUser);
        }
    }

    @Override
    public void delete(XsUserDto xsUserDto) {
        XsUser xsUser = new XsUser();
        xsUser.setUserId(xsUserDto.getUserId());
        xsUser.setDelFalg("1");
        xsUser.setUpdateTime(new Date());
        xsUser.setUpdateUser(UserUtils.getCurrentUser().getUid());
        xsUser.setDelTime(new Date());
        xsUserDao.update(xsUser);
    }

    @Override
    public XsUserDto updatePwd(XsUserDto xsUserDto) {
        XsUser xsUser = xsUserDao.selectUserByUserId(UserUtils.getCurrentUser().getUid());
        BeanUtils.copyProperties(xsUser,xsUserDto);
        return xsUserDto;
    }

    @Override
    public AjaxResponseStatus updatePassword(XsUserDto xsUserDto) {
        AjaxResponseStatus ajaxResponseStatus = new AjaxResponseStatus();
        try{
            int count = xsUserDao.selectUserByUserName(xsUserDto.getUserId(),xsUserDto.getUserName());
            if(count>0){
                ajaxResponseStatus.setStatusCode(500);
                ajaxResponseStatus.setMessage("用户名已有人注册");
            }else{
                count=xsUserDao.selectUserByPhoneNum(xsUserDto.getUserId(),xsUserDto.getPhoneNum());
                if(count>0){
                    ajaxResponseStatus.setStatusCode(500);
                    ajaxResponseStatus.setMessage("该手机号已有人注册");
                }else{
                    XsUser user = xsUserDao.selectUserByUserId(xsUserDto.getUserId());
                    String uPassword = SecurityUtils.md5(xsUserDto.getUpPassWord(),user.getSalt());
                    String password = SecurityUtils.md5(xsUserDto.getPassWord(),user.getSalt());
                    if(user.getPassWord().equals(password)){
                        user.setPassWord(uPassword);
                        xsUserDao.update(user);
                        ajaxResponseStatus.setStatusCode(200);
                        ajaxResponseStatus.setMessage("修改成功");
                    }else{
                        ajaxResponseStatus.setStatusCode(500);
                        ajaxResponseStatus.setMessage("原密码错误，请重新输入");
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            ajaxResponseStatus.setStatusCode(500);
            ajaxResponseStatus.setMessage("请重新操作");
        }
        return ajaxResponseStatus;
    }
}
